package com.cate.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.cate.base.BasePageVO;
import com.cate.context.BaseContext;
import com.cate.exception.BusinessException;
import com.cate.mapper.AddressBookMapper;
import com.cate.mapper.OrderDetailMapper;
import com.cate.mapper.OrdersMapper;
import com.cate.mapper.ShoppingCartMapper;
import com.cate.pojo.dto.*;
import com.cate.pojo.entity.AddressBook;
import com.cate.pojo.entity.OrderDetail;
import com.cate.pojo.entity.Orders;
import com.cate.pojo.entity.ShoppingCart;
import com.cate.pojo.vo.OrderStatisticsVO;
import com.cate.pojo.vo.OrderSubmitVO;
import com.cate.pojo.vo.OrderVO;
import com.cate.result.PageResult;
import com.cate.result.SystemCode;
import com.cate.service.OrdersService;
import com.cate.websocket.WebSocketServer;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @CreateTime: 2023/7/30
 * @Author: <==lhd==>
 * @Description:
 */
@Service
@Slf4j
public class OrdersServiceImpl implements OrdersService {

    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private WebSocketServer webSocketServer;


    @Override
    @Transactional
    public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {
        // 1. 查看地址
        log.info("ordersSubmitDTO={}",ordersSubmitDTO);
        final AddressBook addressBook = addressBookMapper.selectById(ordersSubmitDTO.getAddressBookId());

        if(addressBook==null){
            throw new BusinessException(SystemCode.PARAMETER_VALID_ERROR,"地址不存在");
        }

        // 选做：配送范围

        // 2. 检查用户购物车
        Long userId = BaseContext.getCurrentId();

        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(userId);
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.list(shoppingCart);
        if(shoppingCartList==null || shoppingCartList.isEmpty()){
            throw new BusinessException(SystemCode.REQUEST_ERROR,"用户未添加购物车");
        }

        // 3. 创建订单数据
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, orders);
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(Orders.UN_PAID);
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setAddress(addressBook.getDetail());
        orders.setPhone(addressBook.getPhone());
        orders.setConsignee(addressBook.getConsignee());
        orders.setUserId(userId);

        final int i = ordersMapper.insert(orders);
        if(i<=0){
            throw new BusinessException(SystemCode.INNER_ERROR,"创建订单失败");
        }

        // 4. 批量插入订单详情
        List<OrderDetail> orderDetailList = new ArrayList<>();
        for (ShoppingCart cart: shoppingCartList) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart,orderDetail);
            // 订单id
            orderDetail.setOrderId(orders.getId());
            orderDetailList.add(orderDetail);
        }

        orderDetailMapper.insertBatch(orderDetailList);

        // 5. 清空购物车
        shoppingCartMapper.deleteByUserId(userId);

        // 6. 封装返回结果
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                .id(orders.getId())
                .orderNumber(orders.getNumber())
                .orderAmount(orders.getAmount())
                .orderTime(orders.getOrderTime())
                .build();

        return orderSubmitVO;

    }

    @Override
    public void rejectOrder(OrdersRejectionDTO ordersRejectionDTO) {
        Orders orders = BeanUtil.copyProperties(ordersRejectionDTO, Orders.class);
        orders.setStatus(Orders.CANCELLED);
        final int i = ordersMapper.update(orders);
        if (i <= 0) {
            throw new BusinessException(SystemCode.REQUEST_ERROR, "操作失败");
        }
    }

    @Override
    public void cancelOrder(OrdersCancelDTO ordersCancelDTO) {
        Orders orders = BeanUtil.copyProperties(ordersCancelDTO, Orders.class);
        orders.setStatus(Orders.CANCELLED);
        final int i = ordersMapper.update(orders);
        if (i <= 0) {
            throw new BusinessException(SystemCode.REQUEST_ERROR, "操作失败");
        }
    }

    @Override
    public void confirmOrder(OrdersConfirmDTO ordersConfirmDTO) {
        Orders orders = BeanUtil.copyProperties(ordersConfirmDTO, Orders.class);
        orders.setStatus(Orders.CONFIRMED);
        final int i = ordersMapper.update(orders);
        if (i <= 0) {
            throw new BusinessException(SystemCode.REQUEST_ERROR, "操作失败");
        }
    }

    @Override
    public void reminderOrder(Long id) {
        // 根据id查询订单
        Orders ordersDB = ordersMapper.getById(id);

        // 校验订单是否存在
        if (ordersDB == null) {
            throw new BusinessException(SystemCode.REQUEST_ERROR,"订单状态错误");
        }

        Map map = new HashMap();
        map.put("type",2); //1表示来单提醒 2表示客户催单
        map.put("orderId",id);
        map.put("content","订单号：" + ordersDB.getNumber());

        //通过websocket向客户端浏览器推送消息
        webSocketServer.sendToAllClient(JSON.toJSONString(map));
    }

    @Override
    public void completeOrder(Long orderId) {
        Orders orders = new Orders();
        orders.setId(orderId);
        orders.setStatus(Orders.COMPLETED);
        final int i = ordersMapper.update(orders);
        if (i <= 0) {
            throw new BusinessException(SystemCode.REQUEST_ERROR, "操作失败");
        }
    }

    @Override
    public void deliveryOrder(Long orderId) {
        Orders orders = new Orders();
        orders.setId(orderId);
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
        final int i = ordersMapper.update(orders);
        if (i <= 0) {
            throw new BusinessException(SystemCode.REQUEST_ERROR, "操作失败");
        }
    }

    @Override
    public OrderVO getOrdersById(Long id) {
        // 获得订单信息
        final Orders orders = ordersMapper.getById(id);
        // 获得订单项信息
        final List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(id);

        OrderVO orderVO = BeanUtil.copyProperties(orders, OrderVO.class);
        orderVO.setOrderDishes(orderDetailList.toString());
        orderVO.setOrderDetailList(orderDetailList);
        return orderVO;
    }

    @Override
    public OrderStatisticsVO getOrderStatistics() {
        OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();
        orderStatisticsVO.setConfirmed(ordersMapper.countByStatus(Orders.CONFIRMED));
        orderStatisticsVO.setDeliveryInProgress(ordersMapper.countByStatus(Orders.DELIVERY_IN_PROGRESS));
        orderStatisticsVO.setToBeConfirmed(ordersMapper.countByStatus(Orders.TO_BE_CONFIRMED));
        return orderStatisticsVO;
    }

    @Override
    public BasePageVO<Orders> pageQuery(OrdersPageQueryDTO ordersPageQueryDTO) {
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        final Page<Orders> ordersPage = ordersMapper.pageQuery(ordersPageQueryDTO);
        return new BasePageVO<>(ordersPage.getTotal(),ordersPage.getResult());
    }

    @Override
    public BasePageVO<OrderVO> pageQueryForUser(int page, int pageSize, Integer status) {
        // 设置分页
        PageHelper.startPage(page, pageSize);

        OrdersPageQueryDTO ordersPageQueryDTO = new OrdersPageQueryDTO();
        ordersPageQueryDTO.setUserId(BaseContext.getCurrentId());
        ordersPageQueryDTO.setStatus(status);
        // 分页条件查询
        Page<Orders> pageData = ordersMapper.pageQuery(ordersPageQueryDTO);

        List<OrderVO> list = new ArrayList();


        // 查询出订单明细，并封装入OrderVO进行响应
        if (pageData != null && pageData.getTotal() > 0) {
            for (Orders orders : pageData) {
                Long orderId = orders.getId();// 订单id

                // 查询订单明细
                List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(orderId);

                OrderVO orderVO = new OrderVO();
                orderVO.setOrderDishes(JSONUtil.toJsonStr(orderDetails));
                BeanUtils.copyProperties(orders, orderVO);
                orderVO.setOrderDetailList(orderDetails);

                list.add(orderVO);
            }
        }
        return new BasePageVO<OrderVO>(pageData.getTotal(), list);
    }

    @Override
    public void paymentOrder(OrdersPaymentDTO ordersPaymentDTO) {
        // 获得订单信息
        Long userId = BaseContext.getCurrentId();
        final Orders orders = ordersMapper.getByOrderNumberAndUserId(ordersPaymentDTO.getOrderNumber(), userId);
        if(orders==null){
            throw new BusinessException(SystemCode.INNER_ERROR);
        }
        // 设置订单状态
        Orders order = new Orders();
        order.setId(orders.getId());
        order.setPayStatus(Orders.PAID);
        order.setStatus(Orders.TO_BE_CONFIRMED);
        final int i = ordersMapper.update(order);
        if(i<=0){
            throw new BusinessException(SystemCode.INNER_ERROR,"支付失败");
        }
        Map map = new HashMap();
        map.put("type",1); //1表示来单提醒 2表示客户催单
        map.put("orderId",orders.getId());
        map.put("content","订单号：" + orders.getNumber());

        //通过websocket向客户端浏览器推送消息
        webSocketServer.sendToAllClient(JSON.toJSONString(map));
    }

    @Override
    public void repetitionOrder(Long OrderId) {
        // 查询当前用户id
        Long userId = BaseContext.getCurrentId();

        // 根据订单id查询当前订单详情
        List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(OrderId);

        // 将订单详情对象转换为购物车对象
        List<ShoppingCart> shoppingCartList = orderDetailList.stream().map(x -> {
            ShoppingCart shoppingCart = new ShoppingCart();

            // 将原订单详情里面的菜品信息重新复制到购物车对象中
            BeanUtils.copyProperties(x, shoppingCart, "id");
            shoppingCart.setUserId(userId);
            shoppingCart.setCreateTime(LocalDateTime.now());

            return shoppingCart;
        }).collect(Collectors.toList());

        // 将购物车对象批量添加到数据库
        shoppingCartMapper.insertBatch(shoppingCartList);
    }

}
